package com.rlyy.basic.resolver;

import com.rlyy.common.enums.CommonEnum;
import com.rlyy.common.exception.ParameterParseException;
import com.rlyy.common.param.Request;
import com.rlyy.common.param.RequestWrapper;
import com.rlyy.basic.resolver.argument.MyHandlerMethodArgumentResolver;
import com.rlyy.basic.resolver.valid.IMyValidatedPostProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;

/**
 * 参数解析封装
 *
 * @author yuanqinglong
 * @since 2020/7/20 10:30
 */
@Component
public class ParameterParsing extends AbstractParameterParse {

    static final Logger logger = LoggerFactory.getLogger(ParameterParsing.class);
    /**
     * 注入所有的参数解析器
     */
    @Autowired
    private List<MyHandlerMethodArgumentResolver> myHandlerMethodArgumentResolvers;

    /**
     * 自定义的处理业务逻辑之前处理
     */
    @Autowired
    private List<IMyValidatedPostProcessor> myValidatedPostProcessors;

    /**
     * 根据方法参数类型进行解析封装
     *
     * @param handlerMethod 执行方法
     * @param fullRequest   参数
     * @return 执行目标方法所需参数
     * @throws Exception 解析异常
     */
    @Override
    public Object[] parsePackageParameters(HandlerMethod handlerMethod, Request fullRequest) throws Exception {
        Method method = handlerMethod.getMethod();
        Parameter[] parameters = method.getParameters();
        Object[] argsArray = new Object[parameters.length];
        try {
            // 获取默认参数解析器
            for (int i = 0; i < parameters.length; i++) {
                Parameter parameter = parameters[i];
                for (MyHandlerMethodArgumentResolver resolver : myHandlerMethodArgumentResolvers) {
                    if (resolver.supportsParameter(parameter)) {
                        Object parsedParameters = resolver.resolveArgument(parameter, fullRequest);
                        argsArray[i] = parsedParameters;
                        break;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("参数解析异常", e);
            throw (e instanceof ParameterParseException) ? e : new ParameterParseException(CommonEnum.PARAMETER_PARSING_ERROR);
        }
        // 请求到达控制器之前执行  此处预留对参数校验的扩展功能
        this.myValidatedPostProcessors(argsArray, handlerMethod);
        return argsArray;
    }


    /**
     * 执行自定义参数校验逻辑
     *
     * @param params        参数
     * @param handlerMethod 执行方法及声明类
     */
    private void myValidatedPostProcessors(Object[] params, HandlerMethod handlerMethod) {
        RequestWrapper requestWrapper = new RequestWrapper(params, handlerMethod);
        if (!CollectionUtils.isEmpty(myValidatedPostProcessors)) {
            for (IMyValidatedPostProcessor myValidatedPostProcessor : myValidatedPostProcessors) {
                if (myValidatedPostProcessor.supportsValid(requestWrapper)) {
                    myValidatedPostProcessor.validate(requestWrapper);
                    return;
                }
            }
        }
    }
}
